package hu.myai.util.web;

import hu.myai.model.TickVO;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author bozbalint
 *
 */
public class DownloadASXStockData {

    /**
     * The object used when logging debug,errors,warnings and info.
     * */
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    DownloadURLNoCookies webNoCookies = null;

    public DownloadASXStockData() {
    }

    /**
     * Get the symbol code list from asx.com.au
     * */
    public List<String> getCompanyList() {

        List<String> symbolList = new ArrayList<String>();
        DownloadURLNoCookies webNoCookies = new DownloadURLNoCookies();

        try {
            String myUrl = new String("http://www.asx.com.au/asx/downloadCsv/ASXListedCompanies.csv");

            // read date from web
            InputStream rawInStream = webNoCookies.getURLGetString(new URL(myUrl));

            // error not data was read
            if (rawInStream == null) {
                return symbolList;
            }

            BufferedReader response = new BufferedReader(new InputStreamReader(rawInStream));

            String line = null;
            // remove the header
            for (int i = 0; i < 4; i++)
                line = response.readLine();
            // Start EntityManagerFactory

            while (line != null && !line.equals("") && line.indexOf(",") != -1) {

                StringTokenizer tokens = new StringTokenizer(line, ",\n");
                if (tokens.countTokens() >= 2) {

                    @SuppressWarnings("unused")
                    String companyName = tokens.nextToken();

                    String symbol = tokens.nextToken();

                    @SuppressWarnings("unused")
                    String group = tokens.nextToken();

                    /** check whatever is in the symbol list */
                    // if (Constans.forCheckSymbol.indexOf(symbol) != -1) {
                    /** check if it is a ordinary stock or not */
                    if (symbol.length() == 3) {

                        symbolList.add(symbol);
                    }
                }
                line = response.readLine();
            }

            response.close();

            log.info("Get Sanford data end.");

        } catch (IOException ex) {
            log.error("IOException thrown while initializing the ASX. Message is : " + ex.getMessage());
            return null;
        } catch (Exception ex) {
            log.error("Exception thrown while initializing the ASX. Message is : " + ex.getMessage());
            return null;
        }

        return symbolList;
    }

    public List<TickVO> getYahooHistory(Date startDate, Date endDate, String symbol) {

        List<TickVO> tickList = new ArrayList<TickVO>();

        log.info("Get Sanford symbol for: " + symbol);

        SimpleDateFormat formatter;

        String line = "", myUrl = "";

        DownloadURLNoCookies webNoCookies = new DownloadURLNoCookies();

        Calendar startCal = Calendar.getInstance();
        startCal.setTime(startDate);

        Calendar endCal = Calendar.getInstance();
        endCal.setTime(endDate);

        try {
            myUrl = new String("http://ichart.finance.yahoo.com/table.csv?" + "s=" + symbol + ".AX&a="
                    + startCal.get(Calendar.MONTH) + "&b=" + startCal.get(Calendar.DATE) + "&c="
                    + startCal.get(Calendar.YEAR) + "&d=" + endCal.get(Calendar.MONTH) + "&e="
                    + endCal.get(Calendar.DATE) + "&f=" + startCal.get(Calendar.YEAR) + "&g=d&ignore=.csv");

            // read date from web
            InputStream rawInStream = webNoCookies.getURLGetString(new URL(myUrl));

            /** Error handling: not data was read */
            if (rawInStream == null) {
                return null;
            }
            BufferedReader response = new BufferedReader(new InputStreamReader(rawInStream));

            /** Skipp the header */
            for (int i = 0; i < 2; i++)
                line = response.readLine();

            List<String> recordList = new ArrayList<String>();

            /** makes reverse order */
            while (line != null && !line.equals("") && line.indexOf(",") != -1) {
                recordList.add(0, line);
                line = response.readLine();
            }
            response.close();

            /** store records to the database */
            for (String recLine : recordList) {
                line = recLine;
                StringTokenizer tokens = new StringTokenizer(line, ",\n");
                if (tokens.countTokens() >= 5) {

                    /** check whatever is in the symbol list */
                    // if (Constans.forCheckSymbol.indexOf(symbol) != -1) {
                    /** check if it is a ordinary stock or not */
                    formatter = new SimpleDateFormat("yyyy-MM-dd");
                    Date date = formatter.parse(tokens.nextToken());

                    Double open = new Double(tokens.nextToken());
                    Double high = new Double(tokens.nextToken());
                    Double low = new Double(tokens.nextToken());
                    Double close = new Double(tokens.nextToken());
                    Integer volume = new Integer(tokens.nextToken());

                    if (open == 0.0 && close == 0.0 && high == 0.0 && low == 0.0 && volume == 0) {
                        log.error("Error - not valid record from Yahoo: " + symbol + ", " + date);
                        // cannot loose this information
                        // continue;
                    }

                    // consolidate the result
                    if (open == 0.0)
                        open = close != 0.0 ? close : (high != 0.0 ? high : low);
                    if (high == 0.0)
                        high = close != 0.0 ? close : (open != 0.0 ? open : low);
                    if (low == 0.0)
                        low = close != 0.0 ? close : (high != 0.0 ? high : open);
                    if (close == 0.0)
                        close = low != 0.0 ? low : (high != 0.0 ? high : open);

                    TickVO tick = new TickVO();
                    tick.setOpen(open);
                    tick.setHigh(high);
                    tick.setLow(low);
                    tick.setClose(close);
                    tick.setVolume(volume);
                    tick.setTime(date);
                    tick.setSymbol(symbol);

                    tickList.add(tick);
                }
            }

        } catch (IOException ex) {
            log.error("IOException thrown while initializing the Yahoo. Message is : " + ex.getMessage());
            return null;
        } catch (Exception ex) {
            log.error("Exception thrown while initializing the Yahoo. Message is : " + ex.getMessage());
            return null;
        }

        return tickList;
    }
}
